/// @tags: NodeDiv
#include <cstdio>
#include <cstring>
#include <iostream>
#include <vector>

using namespace std;

namespace BlueQuantum {

typedef vector<int>::iterator IIter;

int const N = 1e5 + 5;

int n, m, tot, rt;
int e_cnt;
int heads[N], siz[N], maxn[N], buk[N], dep[N], ans[N];
bool vis[N];
vector<int> vec[N];

struct Query {
  int k, ans, id;
};

typedef vector<Query>::iterator QIter;
vector<Query> q[N];

struct Edge {
  int v, nxt;
} e[N << 1];

inline void add(int u, int v) {
  e[++e_cnt].v = v, e[e_cnt].nxt = heads[u], heads[u] = e_cnt;
}

void getRT(int u, int fa) {
  maxn[u] = 0, siz[u] = 1;
  for (int i = heads[u], v; i; i = e[i].nxt) {
    if (vis[v = e[i].v] == false && v != fa) {
      getRT(v, u);
      siz[u] += siz[v];
      if (siz[v] > maxn[u]) maxn[u] = siz[v];
    }
  }
  if (maxn[u] < tot - siz[u]) maxn[u] = tot - siz[u];
  if (maxn[rt] > maxn[u]) rt = u;
}

void getDep(int u, int fa, int ffa) {
  vec[ffa].push_back(u);
  buk[dep[u]]++;
  for (int i = heads[u], v; i; i = e[i].nxt) {
    if (vis[v = e[i].v] == false && v != fa) {
      dep[v] = dep[u] + 1;
      getDep(v, u, ffa);
    }
  }
}

void solve(int u) {
  vis[u] = true;
  buk[0] = 1;
  for (int i = heads[u], v; i; i = e[i].nxt) {
    if (vis[v = e[i].v] == false) dep[v] = 1, getDep(v, v, v);
  }
  for (int i = heads[u], v; i; i = e[i].nxt) {
    if (vis[v = e[i].v] == false) {
      for (IIter j = vec[v].begin(), jlim = vec[v].end(); j != jlim; ++j) {
        buk[dep[*j]]--;
      }
      for (IIter j = vec[v].begin(), jlim = vec[v].end(); j != jlim; ++j) {
        for (QIter h = q[*j].begin(), hlim = q[*j].end(); h != hlim; ++h) {
          if (dep[*j] <= h->k) h->ans += buk[h->k - dep[*j]];
        }
      }
      for (IIter j = vec[v].begin(), jlim = vec[v].end(); j != jlim; ++j) {
        buk[dep[*j]]++;
      }
    }
  }
  for (QIter i = q[u].begin(), lim = q[u].end(); i != lim; ++i) { i->ans += buk[i->k]; }
  for (int i = heads[u], v; i; i = e[i].nxt) {
    if (vis[v = e[i].v] == false)
      for (IIter it = vec[v].begin(), lim = vec[v].end(); it != lim; ++it) {
        buk[dep[*it]] = 0;
      }
    vec[v].clear();
    vector<int>(vec[v]).swap(vec[v]);
  }
  buk[0] = 0;
  for (int i = heads[u], v; i; i = e[i].nxt) {
    if (vis[v = e[i].v] == false) {
      rt = 0, tot = siz[v];
      getRT(v, u);
      solve(rt);
    }
  }
}

inline int main() {
  int T;
  cin >> T;
  while (T--) {
    e_cnt = 0;
    memset(heads, 0, sizeof(heads));
    memset(vis, 0, sizeof(vis));
    cin >> n >> m;
    for (int i = 1, u, v; i < n; ++i) {
      cin >> u >> v;
      add(u, v), add(v, u);
    }
    for (int i = 1, x, k; i <= m; ++i) {
      cin >> x >> k;
      q[x].push_back((Query){k, 0, i});
    }
    tot = n, rt = 0, maxn[0] = 0x3f3f3f3f;
    getRT(1, 1);
    solve(rt);
    for (int i = 1; i <= n; ++i) {
      for (QIter it = q[i].begin(), lim = q[i].end(); it != lim; ++it) {
        ans[it->id] = it->k != 0 ? it->ans : 1;
      }
      q[i].clear();
    }
    for (int i = 1; i <= m; ++i) cout << ans[i] << '\n';
  }
  return 0;
}

}  // namespace BlueQuantum

int main() {
#ifndef ONLINE_JUDGE
#ifdef LOCAL
  freopen("/tmp/CodeTmp/testdata.in", "r", stdin);
  freopen("/tmp/CodeTmp/testdata.out", "w", stdout);
#else
  freopen("P6626 [省选联考 2020 B 卷] 消息传递.in", "r", stdin);
  freopen("P6626 [省选联考 2020 B 卷] 消息传递.out", "w", stdout);
#endif
#endif

  ios::sync_with_stdio(false), cin.tie(NULL), cout.tie(NULL);
  return BlueQuantum::main();
}